package netty.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/**
 * Created by IntelliJ
 * Author:熊磊
 */

/**
 * 自定义handler
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * 读取客户端数据
     *
     * @param ctx 上下文对象 , 含有管道 通道 地址
     * @param msg 客户端发送的数据
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println(Thread.currentThread().getName()); //nioEventLoopGroup-3-1
        //System.out.println("服务器读取线程是: "+Thread.currentThread().getName());
        //System.out.println("server ctx = " + ctx);
        //
        //System.out.println("看看channel 和 pipeline的关系");
        //ChannelPipeline pipeline = ctx.pipeline();
        //Channel channel = ctx.channel(); //用debug 查看
        //
        //
        ////ByteBuf 是netty 提供的
        //ByteBuf buf = (ByteBuf) msg;
        //System.out.println("客户端发送的消息是: " + buf.toString(CharsetUtil.UTF_8));
        //System.out.println("客户端地址: " + ctx.channel().remoteAddress());

        //任务队列
        //比如我们有一个非常耗时的工作 -> 异步执行 ->提交该channel 对应的
        //Thread.sleep(10*1000);  //同步会阻塞
        //ctx.writeAndFlush(Unpooled.copiedBuffer("读取工作完成",CharsetUtil.UTF_8));

        //解决方案 1
        //获取到eventLoop , 给他一个任务

        ctx.channel().eventLoop().execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(10);
                ctx.writeAndFlush(Unpooled.copiedBuffer(Thread.currentThread().getName() + "完成任务1", CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("发生异常");
            }
        });


        //解决方案2
        //用户自定义定时任务
        ctx.channel().eventLoop().schedule(() -> {

            ctx.writeAndFlush(Unpooled.copiedBuffer(Thread.currentThread().getName() + "完成定时任务", CharsetUtil.UTF_8));

        }, 5, TimeUnit.SECONDS);

        //普通任务与定时任务按顺序执行
        System.out.println();
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println(Thread.currentThread().getName());  //nioEventLoopGroup-3-2
        // write  +  flush
        // 将数据写入到缓冲 , 并刷新
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端~", CharsetUtil.UTF_8));
    }

    //处理异常 , 一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
